#pragma once
#include <iostream>
using namespace std;
#include <string>
#include <functional>
#include <pthread.h>
#include <cassert>

//class Thread;

// 上下文：用来去调用新线程执行流的函数
//  class Context{
//  public:
//      Context():_this(nullptr),_args(nullptr){

//     }
//     ~Context(){

//     }
// public:
//     Thread* _this;
//     void* _args;
// };

namespace ThreadNs
{

    class Thread
    {
    public:
        typedef function<void *(void *)> func_t; // 这里封装的就是新线程的执行流

        // 构造函数：封装的是pthread_create()
        // 要传入的参数有新线程的执行流，执行流的参数，编号
        Thread()
        {
            char buffer[1024];
            snprintf(buffer, sizeof buffer, "thread:%d", threadnum++);
            _name = buffer;
        }

        void start(func_t func, void *args = nullptr)
        {   
            _func = func;
            _args = args;
            int n = pthread_create(&_tid, nullptr, start_routine, this);
            assert(n == 0);
            (void)n;
        }

        // 在类创建线程，想让线程执行对应的方法，需要将方法设置为静态，这样就没有this指针了
        static void *start_routine(void *args)
        { // 类内成员函数，有一个隐藏的this指针，所以创建线程只能传一个参数是不对的
            // 所以这里使用一个类来接受2个传参，一个this，一个args
            // return _func(_args);
            Thread *n = static_cast<Thread *>(args);
            return n->callback();
            // 静态方法不能调用成员方法或者成员变量
        }

        void join()
        {
            int n = pthread_join(_tid, nullptr);
            assert(n == 0);
            (void)n;
        }
        string threadname(){
            return _name;
        }

        void *callback()
        {
            return _func(_args);
        }

        ~Thread()
        {
            // do nothing
        }

    private:
        string _name;   // 创建出来的线程名称
        pthread_t _tid; // 构造的tid，也就是新线程的tid
        func_t _func;   // 新线程的执行流
        void *_args;

        static int threadnum;
    };
    int Thread::threadnum = 1;

};